package principal;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import exceptions.ExecaoHalt;
import exceptions.ExecaoInstrucaoInexistente;
import exceptions.ExecaoMnemonicoInexistente;
import exceptions.ExecaoMontador;
import exceptions.ExecaoNumeroForaDosLimites;
import exceptions.ExecaoRegistradorInexistente;
import exceptions.ExecaoRotuloNaoDefinido;
import exceptions.ExecaoRotuloSemInstrucao;

import model.LinhaDeExecucao;
import model.Simulador;
import basics.ConversaoDeBases;

public class Principal {

	public static void main(String[] args) throws IOException {

		// Abre arquivo
		File f = new File("Arquivos/entrada.txt");
		FileReader fr = new FileReader(f);
		BufferedReader br = new BufferedReader(fr);

		ArrayList<String> assemblyCodes = new ArrayList<String>();

		while (br.ready()) {
			assemblyCodes.add(br.readLine());

		}

		Simulador mips = new Simulador();

		ArrayList<LinhaDeExecucao> listaDeExecucao = null;
		try {
			listaDeExecucao = mips.executaMontagem(assemblyCodes);
		} catch (ExecaoRotuloSemInstrucao e) {
			// TODO Auto-generated catch block
			System.out.println(e.getLinha() + ": Rótulo sem instrução!");
		} catch (ExecaoNumeroForaDosLimites e) {
			// TODO Auto-generated catch block
			System.out.println(e.getLinha() + ": Número fora dos limites!");
		} catch (ExecaoRotuloNaoDefinido e) {
			// TODO Auto-generated catch block
			System.out.println(e.getLinha() + ": Rótulo não definido!");
		} catch (ExecaoMnemonicoInexistente e) {
			// TODO Auto-generated catch block
			System.out.println(e.getLinha() + ": Comando MIPS inexistente!");
		} catch (ExecaoRegistradorInexistente e) {
			// TODO Auto-generated catch block
			System.out.println(e.getLinha() + ": Registrador inexistente!");
		} catch (ExecaoMontador e) {
			// TODO Auto-generated catch block
			System.out.println("Erro de montagem!");
		}

		try {
			for (LinhaDeExecucao linhaDeExecucao : listaDeExecucao) {
				System.out.println(linhaDeExecucao.getEnderecoDecimal() + "\t"
						+ linhaDeExecucao.getCodigoMaquina() + "\t"
						+ linhaDeExecucao.getInstrucaoMips());
			}
		} catch (NullPointerException e) {
			e.printStackTrace();
		}

		try {
			mips.executaTodasInstrucoes();
		} catch (ExecaoInstrucaoInexistente e) {
			// TODO Auto-generated catch block
			System.out.println(e.getEndereco() + ": instrução inexistente!");
		} catch (ExecaoHalt e) {
			// TODO Auto-generated catch block
			System.out.println(e.getEndereco() + ": halt encontrado!");
		}

		String[] memoriaArray = mips.getMemoria(0, 199);

		System.out.println("\n\n====================Memória=============================");

		if (memoriaArray != null) {
			for (int i = 0; i < memoriaArray.length; i += 4) {
				System.out.println(ConversaoDeBases.decToHex(i)
						+ " : "
						+ ConversaoDeBases.binToHex((memoriaArray[i]
								+ memoriaArray[i + 1] + memoriaArray[i + 2] + memoriaArray[i + 3]))
						+ "\t\t\t"
						+ +ConversaoDeBases.binToDecSigned((memoriaArray[i]
								+ memoriaArray[i + 1] + memoriaArray[i + 2] + memoriaArray[i + 3])));
			}
		}

		System.out.println("========================================================");

		System.out.println("\n\n====================Registradores=======================");
		String[] regValores = mips.getRegistradores();
		for (int i = 0; i < 32; i++) {
			System.out.println("reg[" + i + "] = \t"
					+ ConversaoDeBases.binToHex(regValores[i]) + "\t\t\t"
					+ +ConversaoDeBases.binToDecSigned((regValores[i])));
		}
		System.out.println("========================================================");

	}
}
